
package com.framework.sec.util.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.framework.bas.bs.IPlmBasBS;
import com.framework.bas.param.GeneralParam;
import com.framework.bas.service.IControl;
import com.framework.bas.util.PlmBasConstant;
import com.framework.bas.util.UtilWeb;
import com.framework.bas.vo.BasService;
import com.framework.sec.bs.IPlmSecBS;
import com.framework.sec.util.PlmSecConstant;
import com.framework.sog.util.PlmSogConstant;

public class SecUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
	private boolean isCheckCode = false;
	public static final String VALIDATE_CODE = "validateCode";
	public static final String USERNAME = "j_username";
	public static final String PASSWORD = "j_password";
	private IPlmBasBS plmBasBS;
	private IPlmSecBS plmSecBS;
	private IControl plmBasControl;
	

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
		if (!request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
		}
		//检测验证码
		checkValidateCode(request);
		
		String username = obtainUsername(request);
		String password = obtainPassword(request);
		
		//验证用户账号与密码是否对应
		username = username.trim();
		//UsernamePasswordAuthenticationToken实现 Authentication
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
		// 允许子类设置详细属性
        setDetails(request, authRequest);
        // 运行UserDetailsService的loadUserByUsername 再次封装Authentication
        Authentication au = this.getAuthenticationManager().authenticate(authRequest);
        
        //登录业务处理
        GeneralParam param = doService(username,request.getRemoteAddr());
        //登录成功初始化session
        initSession(request,param,username);
		return au;
	}
	
	private GeneralParam doService(String username, String remoteAddr) {
		GeneralParam param = GeneralParam.getCurrent();
		param.setValue(PlmSecConstant.LOGIN_USERNAME, username);
		param.setValue(PlmSecConstant.LOGIN_IP, remoteAddr);
		
		if (param.getValueObject(PlmBasConstant.APP_SERVICE) == null) {
			param.setValue(PlmBasConstant.APP_SERVICE, PlmSogConstant.SERVICE_ID_SOG0001);
			//封装交易信息
			BasService hpBasServiceVO = getPlmBasBS().queryServiceByCode(
					PlmSogConstant.SERVICE_ID_SOG0001);
			param.setValue(PlmBasConstant.APP_SERVICE_OBJECT, hpBasServiceVO);
		}
		plmBasControl.execute(PlmSogConstant.SERVICE_ID_SOG0001, param);
		
		return param;
	}

	private void initSession(HttpServletRequest httpRequest, GeneralParam param,String userName) {
		httpRequest.getSession().setAttribute(PlmBasConstant.SES_CONTEXT_PATH, httpRequest.getContextPath());
		
		httpRequest.getSession().setAttribute(PlmBasConstant.SES_USER_AUTH_OBJECT, param.getValueObject(PlmSecConstant.USER_AUTH_OBJ));
		
		httpRequest.getSession().setAttribute(PlmBasConstant.SES_USER_LOGON_INFO, param.getAppUser());
		
		httpRequest.getSession().setAttribute(PlmBasConstant.SES_SYS_FLAG, UtilWeb.getSysFlag());
		httpRequest.getSession().setAttribute(PlmBasConstant.SES_VALID_ID, param.getAppValidId());
		httpRequest.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, userName);
		
	}
	
	protected void checkValidateCode(HttpServletRequest request) { 
		HttpSession session = request.getSession();
		
	    String sessionValidateCode = obtainSessionValidateCode(session); 
	    //让上一次的验证码失效
	    session.setAttribute(VALIDATE_CODE, null);
	    String validateCodeParameter = obtainValidateCodeParameter(request);  
	    if(isCheckCode){
	    	if (StringUtils.isEmpty(validateCodeParameter) || !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {  
	    		throw new AuthenticationServiceException("验证码错误！");  
	    	}  
	    }
	}
	
	private String obtainValidateCodeParameter(HttpServletRequest request) {
		Object obj = request.getParameter(VALIDATE_CODE);
		return null == obj ? "" : obj.toString();
	}

	protected String obtainSessionValidateCode(HttpSession session) {
		Object obj = session.getAttribute(VALIDATE_CODE);
		return null == obj ? "" : obj.toString();
	}

	@Override
	protected String obtainUsername(HttpServletRequest request) {
		Object obj = request.getParameter(USERNAME);
		return null == obj ? "" : obj.toString();
	}

	@Override
	protected String obtainPassword(HttpServletRequest request) {
		Object obj = request.getParameter(PASSWORD);
		return null == obj ? "" : obj.toString();
	}

	public void setPlmBasBS(IPlmBasBS plmBasBS) {
		this.plmBasBS = plmBasBS;
	}

	public IPlmBasBS getPlmBasBS() {
		return plmBasBS;
	}

	public void setPlmSecBS(IPlmSecBS plmSecBS) {
		this.plmSecBS = plmSecBS;
	}

	public IPlmSecBS getPlmSecBS() {
		return plmSecBS;
	}

	public void setPlmBasControl(IControl plmBasControl) {
		this.plmBasControl = plmBasControl;
	}

	public IControl getPlmBasControl() {
		return plmBasControl;
	}

	public void setIsCheckCode(boolean isCheckCode) {
		this.isCheckCode = isCheckCode;
	}

	public boolean getIsCheckCode() {
		return isCheckCode;
	}

	
	
}